﻿using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using P2P.Main.Enums;
using P2P.Main.Model;
using P2P.Main.Session;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using P2P.Network.ExtensionMethods;
namespace P2P.Main.Handler
{
    /// <summary>
    /// 客户端NAT穿透协调Handler
    /// </summary>
    public class ClientMakeHoleHandler
    {
        private ApiProtocol apiProtocol;

        public ClientMakeHoleHandler(ApiProtocol apiProtocol)
        {
            this.apiProtocol = apiProtocol;
        }

        /// <summary>
        /// 客户端打洞
        /// </summary>
        public void MakeHole() 
        {
            Direction direction = (Direction)(int)apiProtocol.Params["Direction"];
            string from = (string)apiProtocol.Params["From"];
            string to = (string)apiProtocol.Params["To"];

            if (Direction.OTHER == direction)
            {
                ActiveNode activeNode = ActiveNodeSessionManager.Instance.Find(to);

                JObject data = new JObject();
                data.Add("Name", "P2PMakeHoleHandler");
                data.Add("Method", "P2PMakeHole");
                data.Add("Version", "1.0");

                JObject param = new JObject();
                param.Add("From", from);
                param.Add("Direction", (int)direction);
                param.Add("To", to);
                data.Add("Params", param);
                string ack = JsonConvert.SerializeObject(R<JObject>.Ok(data));

                apiProtocol.Socket.SendTo(ack, activeNode.IP, activeNode.UdpPublicPort);
            }
            else if (Direction.LOCAL == direction) 
            {
                ActiveNode activeNode = ActiveNodeSessionManager.Instance.Find(from);

                JObject data = new JObject();
                data.Add("Name", "P2PMakeHoleHandler");
                data.Add("Method", "P2PMakeHole");
                data.Add("Version", "1.0");

                JObject param = new JObject();
                param.Add("From", from);
                param.Add("Direction", (int)direction);
                param.Add("To", to);
                data.Add("Params", param);
                string ack = JsonConvert.SerializeObject(R<JObject>.Ok(data));

                apiProtocol.Socket.SendTo(ack, activeNode.IP, activeNode.UdpPublicPort);
            }
            else if (Direction.FIRST_LOCAL_THEN_OTHER == direction)
            {
                ActiveNode activeNode = ActiveNodeSessionManager.Instance.Find(to);

                JObject data = new JObject();
                data.Add("Name", "P2PMakeHoleHandler");
                data.Add("Method", "P2PMakeHole");
                data.Add("Version", "1.0");

                JObject param = new JObject();
                param.Add("From", from);
                param.Add("Direction", (int)direction);
                param.Add("To", to);
                data.Add("Params", param);
                string ack = JsonConvert.SerializeObject(R<JObject>.Ok(data));

                apiProtocol.Socket.SendTo(ack, activeNode.IP, activeNode.UdpPublicPort);
            }
            else if (Direction.FIRST_OTHER_THEN_LOCAL == direction)
            {
                ActiveNode activeNode = ActiveNodeSessionManager.Instance.Find(to);

                JObject data = new JObject();
                data.Add("Name", "P2PMakeHoleHandler");
                data.Add("Method", "P2PMakeHole");
                data.Add("Version", "1.0");

                JObject param = new JObject();
                param.Add("From", from);
                param.Add("Direction", (int)direction);
                param.Add("To", to);
                data.Add("Params", param);
                string ack = JsonConvert.SerializeObject(R<JObject>.Ok(data));

                apiProtocol.Socket.SendTo(ack, activeNode.IP, activeNode.UdpPublicPort);
            }
        }
    }
}
